package com.xuly.common;

import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class ActivitiCommonService {
    private final RuntimeService runtimeService;
    private final RepositoryService repositoryService;
    private final TaskService taskService;

    public ActivitiCommonService(RuntimeService runtimeService, RepositoryService repositoryService, TaskService taskService) {
        this.runtimeService = runtimeService;
        this.repositoryService = repositoryService;
        this.taskService = taskService;
    }

    public boolean deploymentProcess(String name, String resourceBpmn) {
        try {
            Deployment deployment = repositoryService.createDeployment()
                    .name(name)
                    .addClasspathResource(resourceBpmn)
                    .deploy();
            log.info("部署成功，部署ID：{}，部署名称：{}", deployment.getId(), deployment.getName());
            return true;
        } catch (Exception e) {
            log.error("部署失败：", e);
            return false;
        }
    }

    public boolean deploymentProcess(String name, String resourceBpmn, String resourcePng) {
        try {
            Deployment deployment = repositoryService.createDeployment()
                    .name(name)
                    .addClasspathResource(resourceBpmn)
                    .addClasspathResource(resourcePng)
                    .deploy();
            log.info("部署成功，部署ID：{}，部署名称：{}", deployment.getId(), deployment.getName());
            return true;
        } catch (Exception e) {
            log.error("部署失败：", e);
            return false;
        }
    }

    public boolean startProcessInstance(String processInstanceKey) {
        try {
            ProcessInstance pi = runtimeService.startProcessInstanceByKey(processInstanceKey);
            log.info("流程启动成功，流程实例ID：{},流程定义ID：{}", pi.getId(), pi.getProcessDefinitionId());
            return true;
        } catch (Exception e) {
            log.error("启动流程失败：", e);
            return false;
        }
    }

    public boolean startProcessInstance(String processInstanceKey, String businessKey) {
        try {
            ProcessInstance pi = runtimeService.startProcessInstanceByKey(processInstanceKey, businessKey);
            log.info("流程启动成功，流程实例ID：{},流程定义ID：{}", pi.getId(), pi.getProcessDefinitionId());
            return true;
        } catch (Exception e) {
            log.error("启动流程失败：", e);
            return false;
        }
    }

    public boolean startProcessInstance(String processInstanceKey, String businessKey, Map<String, Object> params) {
        try {
            ProcessInstance pi = runtimeService.startProcessInstanceByKey(processInstanceKey, businessKey, params);
            log.info("流程启动成功，流程实例ID：{},流程定义ID：{}", pi.getId(), pi.getProcessDefinitionId());
            return true;
        } catch (Exception e) {
            log.error("启动流程失败：", e);
            return false;
        }
    }

    public boolean completeTask(String taskId) {
        try {
            taskService.complete(taskId);
            log.info("任务{}被执行完成", taskId);
            return true;
        } catch (Exception e) {
            log.error("任务执行失败：", e);
            return false;
        }
    }

    public boolean completeTask(String taskId,Map<String,Object> param) {
        try {
            taskService.complete(taskId,param);
            log.info("任务{}被执行完成", taskId);
            return true;
        } catch (Exception e) {
            log.error("任务执行失败：", e);
            return false;
        }
    }

    public void findActTask() {
        List<Task> taskList = taskService.createTaskQuery().active().list();
        if (taskList != null && taskList.size() > 0) {
            for (Task task : taskList) {
                outPrintTaskInfo(task);
            }
        } else {
            log.info("没有找到任务!");
        }
    }

    public void findTaskByProcInsId(String procInsId) {
        List<Task> taskList = taskService.createTaskQuery().active()
                .processInstanceId(procInsId)
                .list();
        if (taskList != null && taskList.size() > 0) {
            for (Task task : taskList) {
                outPrintTaskInfo(task);
            }
        } else {
            log.info("没有找到任务!");
        }
    }

    public void findTaskByAssigneeOrCandidate(String assignee) {
        List<Task> taskList = taskService.createTaskQuery().taskCandidateOrAssigned(assignee)
                .list();
        if (taskList != null && taskList.size() > 0) {
            taskList.forEach(this::outPrintTaskInfo);
        } else {
            log.info("没有找到任务！");
        }
    }

    private void outPrintTaskInfo(Task task) {
        log.info("任务ID:" + task.getId());
        log.info("任务名称:" + task.getName());
        log.info("任务的创建时间:" + task.getCreateTime());
        log.info("任务的办理人:" + task.getAssignee());
        log.info("流程实例ID：" + task.getProcessInstanceId());
        log.info("执行对象ID:" + task.getExecutionId());
        log.info("流程定义ID:" + task.getProcessDefinitionId());
        log.info("业务键businessKey:" + runtimeService.createProcessInstanceQuery()
                .processInstanceId(task.getProcessInstanceId())
                .singleResult().getBusinessKey());
        log.info("********************************************");
    }
}
